"""
page cache for webpy-xblog
author: Mason
starstarstarpku@gmail.com
"""

__all__ = [
    'get_cache', 'edit_post_cache', 'del_all',
    'del_post_cache', 'del_paths_cache', 'add_post_cache',
]

import web
import logging

from google.appengine.api import memcache

def del_all():
  memcache.flush_all()

def del_paths_cache(path_list, log_info):
  for path in path_list:
    logging.debug('"%s", uncaching "%s"' % (log_info, path))
    memcache.delete(path)

def del_pages_cache():
  path_list = []
  log_info = "del page cache"

  for page in range(1000):
    key="/page/"+str(page+1)
    if memcache.get(key):
      path_list.append(key)
    else:
      break
  del_paths_cache(path_list, log_info)
########################################################################

def add_post_cache(post):
  log_info = "add new post"
  del_paths_cache(['/', '/manage', '/archive'], log_info)
  del_paths_cache(['/tag/'+'%s' % tag for tag in set(post.tags)], log_info)
  del_paths_cache(['/date/'+'%s' % post.published_when.strftime("%Y-%m")], log_info)
  del_pages_cache()

def edit_post_cache(post, old_post):
  if (not post.draft) and ((post.title != old_post.title) or \
      (post.tags != old_post.tags)):
    logging.debug('title and/or tags changed. uncache everything')
    del_all()

  else:
    log_info = "post modified"
    del_paths_cache(['/view/' + '%s' % post.id, '/edit/'+'%s' % post.id], log_info)

    if post.title != old_post.title:
      del_paths_cache(['/manage'], "title changed")

    if not post.draft and (old_post.body != post.body or post.title != old_post.title):
      del_paths_cache(['/'], "body/title changed")

    del_paths_cache(['/tag/'+'%s' % tag for tag in set(post.tags + old_post.tags)], "tag uncache")

    # here, delete all pages cache
    # maybe optimize later
    del_pages_cache()

def del_post_cache(post):
  paths = ['/view/' + '%s' % post.id, '/edit/' + '%s' % post.id, '/', '/manage', '/archive'] \
        + ['/tag/'+'%s' % tag for tag in set(post.tags)] + ['/date/'+'%s' % post.published_when.strftime("%Y-%m")]

  del_paths_cache(paths, "post deleted")
  del_pages_cache()

################################################################

"""
two decorators
"""
def get_cache(func):
  def handler(*args):
    path = web.ctx.fullpath
    page = memcache.get(path)
    if page is not None:
      logging.debug('Memcache hit for "%s"' % path)
      return page
    logging.debug('Memcache miss for "%s"' % path)
    page = func(*args)
    if not memcache.set(path, page):
      logging.error('Failed to add "%s" to memcache' % path)
    return page
  return handler

